﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MP3Ganizer.Common.BaseObject;
using Microsoft.Practices.Unity;
using MP3Ganizer.BusinessObject.Services.Configuration;
using MP3Ganizer.BusinessObject.Services.Classification;
using MP3Ganizer.Common.Command;
using Microsoft.Practices.Composite.Events;
using MP3Ganizer.BusinessObject.DataToPersist;
using MP3Ganizer.Common.Interfaces.MassEditor;
using System.Collections.ObjectModel;

namespace MP3Ganizer.Modules.MassEditor.ViewModels
{
    public class AlbumsEditorViewModel : ModuleViewModelBase, IAlbumsEditorViewModel
    {
        private IUnityContainer _unityContainer;
        private IConfigurationService _configurationService;
        private List<string> _albums;
        private string _selectedAlbum;
        private List<KeyValuePair<string, double>> _matchingAlbums;
        private IClassificationService _classificatonService;
        private KeyValuePair<string, double> _albumToReplace;
        private const string REPLACE_FORMAT_TEXT = "Remplacer {0} par {1}";
        private const string UNAVAILABLE_FORMAT_TEXT = "Pas d'éléments sélectionnés";
        private RelayCommand<object> _replaceCommand;
        private IEventAggregator _eventAggregator;
        private ObservableCollection<string> _results;
        public string SelectedAlbum
        {
            get { return _selectedAlbum; }
            set
            {
                _selectedAlbum = value;
                OnPropertyChanged("SelectedAlbum");
                OnPropertyChanged("ReplaceTxt");
                SetMatchingAlbums();
            }
        }
        public List<string> Albums
        {
            get 
            {
                if (_albums == null)
                    return new List<string>();
                return _albums.OrderBy(item => item).ToList(); }
            set
            {
                _albums = value;
                OnPropertyChanged("Albums");
            }
        }
        public KeyValuePair<string, double> AlbumToReplace
        {
            get { return _albumToReplace; }
            set
            {
                _albumToReplace = value;
                OnPropertyChanged("AlbumsToReplace");
                OnPropertyChanged("ReplaceTxt");
            }
        }
        public string ReplaceTxt
        {
            get
            {
                return !(string.IsNullOrEmpty(_selectedAlbum)) && !string.IsNullOrEmpty(_albumToReplace.Key) ? string.Format(REPLACE_FORMAT_TEXT, _albumToReplace.Key, _selectedAlbum) : UNAVAILABLE_FORMAT_TEXT;
            }

        }
        public RelayCommand<object> ReplaceCommand
        {
            get { return _replaceCommand; }
        }
        public IEnumerable<KeyValuePair<string, double>> MatchingAlbums
        {
            get { return _matchingAlbums; }
            private set
            {
                _matchingAlbums = value.ToList();
                OnPropertyChanged("MatchingAlbums");
            }
        }

        public AlbumsEditorViewModel(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
            _eventAggregator = _unityContainer.Resolve<IEventAggregator>();
            _configurationService = _unityContainer.Resolve<IConfigurationService>();
            _classificatonService = _unityContainer.Resolve<IClassificationService>();
            _matchingAlbums = new List<KeyValuePair<string, double>>();
            _replaceCommand = new RelayCommand<object>(ReplaceAction, CanReplace);
            _results = new ObservableCollection<string>();
            _results.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ResultsCollectionChanged);
            _albums = new List<string>();
        }

        
        //public void Initialize()
        //{
        //    _getAlbumsOk = _configurationService.GetInfos<OverridableData>(InfoType.Albums, out _results);
        //    if (_getAlbumsOk)
        //        Albums = _results.Select(item => item.Name);
        //}

        protected override void OnLoad()
        {
           _configurationService.GetInfosObservable(InfoType.Albums, _results);
        }

        void ResultsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if(e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                foreach (var item in e.NewItems)
                {
                    _albums.Add((string)item);
                    if(_albums.Count%1000 == 1)
                        OnPropertyChanged("Albums");
                }
        }


        protected override void OnloadCompleted()
        {
            OnPropertyChanged("Albums");
        }

        private void SetMatchingAlbums()
        {
            if (string.IsNullOrEmpty(_selectedAlbum))
                return;

            _matchingAlbums = new List<KeyValuePair<string, double>>();
            foreach (var album in _albums)
            {
                if (_selectedAlbum.Equals(album))
                    continue;
                double opacity = _classificatonService.GetPercentageOfString(_selectedAlbum, album) / 100;
                if (opacity > 0.3)
                    _matchingAlbums.Add(new KeyValuePair<string, double>(album, opacity));
            }
            MatchingAlbums = _matchingAlbums.OrderByDescending(item => item.Value);
        }

        private void ReplaceAction(object e)
        {
            string albumToReplace = _albumToReplace.Key;

            _configurationService.SetInfo(InfoType.Albums, _selectedAlbum, albumToReplace);
            _albumToReplace = new KeyValuePair<string, double>(null, 0);
            Initialize();
            SetMatchingAlbums();
            base.PropertiesChanged(new string[] { "Albums", "SelectedAlbum", "MatchingAlbums", "ReplaceTxt", "AlbumToReplace" });
            _eventAggregator.GetEvent<MP3Ganizer.Events.User.UserActionEvent>().Publish(new Events.User.UserActionEventArgs(Common.Enums.UserAction.RefreshFileTree));
        }

        private bool CanReplace(object e)
        {
            return !(string.IsNullOrEmpty(_selectedAlbum)) && !string.IsNullOrEmpty(_albumToReplace.Key);
        }
    }
}
